#include "./work_task.h"
#include "../driver/log_uart.h"
#include "../driver/music_uart.h"
#include "../driver/key.h"
#include "../driver/motor.h"
#include "../driver/cmd_uart.h"
#include "../utils/codec.h"
#include "../service/device_info.h"
#include "../driver/display.h"

namespace task {

using namespace driver;
using namespace utils;
using namespace service;

static uint8_t recv_buf[64];

void WorkTask_t::run() {
    m_drop_flag = 0;

    osDelay(200);

    utils::ByteView_t bw;
    utils::Error_t err;
    bw.buf = recv_buf;
    
    for (;;) {
        if (!musicUart->is_busy()) {
            musicUart->play(1);
        }
        if (key->is_key0()) {
            musicUart->add_volume();
        }
        if (key->is_key1()) {
            musicUart->sub_volume();
        }

        err = cmdUart->recv_proto(bw);
        if (err == utils::ec::Ok) {
            exec(bw);
        }

        display->show_price(Right);
    }
}

void WorkTask_t::exec(const utils::ByteView_t &bw) {
    if (!pre_proc(bw)) {
        return;
    }

    uint8_t req = utils::decode_uint8(bw.buf);
    switch (req) {
        case utils::dtu_proto::Delivery: delivery(bw); break;
        case utils::dtu_proto::WinProb: set_price(bw); break;
    }
}

/**
 * 出货:   91 XX, ID1, ID2, ID3, ID4, MM => 7
 * 设置金额: AA XX, YY,ZZ,ZZ,ZZ,ZZ,ZZ,ZZ,ID1,ID2,ID3,ID4,MM => 14  
 */
bool WorkTask_t::pre_proc(const utils::ByteView_t &bw) {
    uint8_t req = decode_uint8(bw.buf);
    uint32_t id = 0;

    switch (req) {
        case dtu_proto::Delivery: 
            if (bw.len < 6) {
                logUart->printf("出货命令参数长度错误:%d", bw.len);
                cmdUart->write_ack(CmdUart_t::Nck, 0);
                return false;
            }
            id = decode_uint32(bw.buf + 2);
            break;

        case dtu_proto::WinProb:
            if (bw.len < 13) {
                logUart->printf("设置金额命令参数长度错误:%d", bw.len);
                cmdUart->write_ack(CmdUart_t::Nck, 0);
                return false;
            }
            id = decode_uint32(bw.buf + 9);
            break;

        default: 
            logUart->printf("未知命令:%d", req);
            cmdUart->write_ack(CmdUart_t::Nck, 0);
            return false;
    }
    cmdUart->write_ack(CmdUart_t::Ack, id);
    return true;
}

static void send_delivery_result(uint8_t xx, uint8_t yy, uint8_t zz, uint32_t id) {
    uint8_t buf[] = {
        0x2b, 12, 0x91,
        xx, yy, zz, 
        id >> 24, id >> 16, id >> 8, id,
        0x0d, 0x0a
    };
    cmdUart->write(buf, sizeof (buf));
}

static void send_step(uint32_t id) {
    send_delivery_result(1, 0, 0, id);
}

static void send_result(bool flag, uint32_t id) {
    uint8_t zz = (flag ? 1 : 0);
    send_delivery_result(4, 1, zz, id);
}

void WorkTask_t::delivery(const utils::ByteView_t &bw) {
    uint8_t price = decode_uint8(bw.buf + 1);
    uint32_t id = decode_uint32(bw.buf + 2);

    add_price(price);
    display->set_price(price);

    if (motor->is_checked()) {
        m_drop_flag = 1;
        send_result(false, id);
        logUart->printf("光栅被遮挡");
        return;
    }

    display->show_price(Left);
    
    musicUart->play(3);
    musicUart->play(3);

    key->wait_knob();
    send_step(id);

    utils::Error_t err = motor->run3();
    if (err == ec::Ok) {
        logUart->printf("出货成功");
        add_sweet();
        musicUart->play(2);
        musicUart->play(2);

        send_result(true, id);
    } else {
        logUart->printf("出货失败");
        send_result(false, id);
    }
    musicUart->wait_busy();
    display->show_price(Right);
}

void WorkTask_t::set_price(const utils::ByteView_t &bw) {
    uint8_t price = decode_uint8(bw.buf + 1);
    logUart->printf("设置金额:%d", price);
    display->set_price(price);
}

}


